/*--------------------------------------------------------------------------------------------------
Yatak Operation System Project Copyright 2012-2013
Author : Ilya Churaev
Started : 17 Jun 2012		Updated : 1 Jun 2013
File Name : paging.h		Purpose : Defines the interface for and structures relating to paging.
--------------------------------------------------------------------------------------------------*/

#ifndef _PAGING_H
#define _PAGING_H

#ifdef __cplusplus
extern "C" {
#endif

#include <types.h>
#include <yatak/isr.h>

#define PAGE_SIZE				0x1000

typedef struct page
{
	uint32 present	:1;			// Страница присутствует в памяти
	uint32 rw		:1;			// Если сброшен, то страница только для чтения,
								// если установлен, то и для чтения и для записи
	uint32 user		:1;			// Если сброшен, то уровень супервизора
	uint32 accessed	:1;			// Было ло обращение к странице, после последнего ее обновления
	uint32 dirty	:1;			// Выполнялась ли запись на страницу после ее последнего обновления
	uint32 unused	:7;			// Все неиспользуемые и зарезервированные биты
	uint32 frame	:20;		// Адрес фрейма (сдвинут вправо на 12 бит)
} page_t;

typedef struct page_table
{
	page_t pages[1024];
} page_table_t;

typedef struct page_directory
{
	// Массив указателей на таблицы страниц
	page_table_t *tables[1024];
	// Массив указателей на таблицы страниц, о которых говорилось выше, но указатели указывают
	// "физическое" местоположение, используемое при загрузке в регистр CR3
	uint32 tablesPhysical [1024];
	// Физический адресс tablesPhysical. Его потребуется использовать в случае, когда мы получаем
	// в ядре память типа куча, а директорий может находиться в любом месте виртуальной памяти
	uint32 physicalAddr;
} page_directory_t;

// Настройка среды окружения, директориев страниц и т.д. включение страничной органицации памяти
void init_paging(unsigned int max_mem);

// Загружает указанный директорий страниц в регистр CR3
void switch_page_directory(page_directory_t *new);

// Поиск указателя на необходимую страницу. Если make == 1 в таблице страниц, в которой эта
// страница должна разполагаться, то страница не создана - создайте страницу!
page_t *get_page(uint32 address, int make, page_directory_t *dir);

// Обработчик некорректного обращения к страницам
void page_fault(registers_t *regs);

// Клонирование директория страниц
page_directory_t *clone_directory(page_directory_t *src);

// Удаление директория страниц
void destroy_directory (page_directory_t *src);

void mem_dump_char(int addr, int bytes);
void mem_dump(int addr, int bytes);

void alloc_frame(page_t *page, int is_kernel, int is_writeable);
void free_frame(page_t *page);

void virtual_map_pages(long addr, long size, int rw, int user);

#ifdef __cplusplus
}
#endif

#endif
